package com.mingqijia.gassafety.webserver.service.cmp.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mingqijia.gassafety.db.entity.*;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.EquipmentStatus;
import com.mingqijia.gassafety.shared.constant.EquipmentType;
import com.mingqijia.gassafety.webserver.dto.ReportNotifyDTO;
import com.mingqijia.gassafety.webserver.dto.ReportNotifyOfflineDTO;
import com.mingqijia.gassafety.webserver.request.cmp.notify.DataReportDataRequest;
import com.mingqijia.gassafety.webserver.request.cmp.notify.DataReportRequest;
import com.mingqijia.gassafety.webserver.service.ReceiverValveService;
import com.mingqijia.gassafety.webserver.service.RecordReceiverValveService;
import com.mingqijia.gassafety.webserver.service.cmp.AbstractCmpDataNotifyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;

import static com.mingqijia.gassafety.webserver.constant.DeviceConstant.*;


/**
 * CMP平台数据上报回调具体实现
 *
 * @author zhufeng
 * @since 2022/8/4
 */
@Service
@Slf4j
public class CmpDataNotifyServiceImpl extends AbstractCmpDataNotifyService {

    @Autowired
    ReceiverValveService receiverValveService;
    @Autowired
    RecordReceiverValveService recordReceiverValveService;

    @Override
    protected DeviceState prepareDeviceState(DataReportRequest request, Dtu dtu) {
        log.info("prepareDeviceState start");
        DeviceState deviceState = new DeviceState();
        deviceState.setDeviceId(dtu.getId());
        deviceState.setSignal(request.getSignal());
        deviceState.setMainBatteryValue(request.getElectricQuantity());
        deviceState.setDetectorCount(request.getDetectorNum());
        deviceState.setSpId(dtu.getSpId());
        // (家报,一体)设备由探测器部分统一决定总状态, 控制器单独决定
        if (EquipmentType.GAS_ALARM_CONTROLLER.getCode().equals(dtu.getEquipmentType())){
            setStatusInfo(request.getControllerStatus(), null, deviceState );
        }
        if (request.getClockAccuracy() != null){
            deviceState.setClockAccuracy(request.getClockAccuracy());
        }
        log.info("prepareDeviceState {} end", JSON.toJSONString(deviceState));
        return deviceState;
    }

    @Override
    protected RecordDetector prepareRecordDetector(DataReportDataRequest t, Dtu newDtu) {
        RecordDetector recordDetector = new RecordDetector();
        recordDetector.setDeviceId(newDtu.getId());
        recordDetector.setSubId(t.getSno());
        recordDetector.setConsumerId(newDtu.getConsumerId());
        recordDetector.setRecordId(t.getRecordId());
        recordDetector.setRecordAt(t.getRecordAt());
        recordDetector.setGasType(t.getGasType());
        recordDetector.setConcentration(t.getConcentration());
        recordDetector.setSpId(t.getSpId());
        boolean isAlarmRecovery = false;
        if( "v1.0".equals(newDtu.getProtocolVersion()) && DETECTOR_STATUS_0.equals(t.getDetectorStatus()) &&
                !Constants.ZJ_EQUIPMENT_FROM.equals(newDtu.getEquipmentFrom()) ){
            DeviceState state = getStateByDeviceId(newDtu.getId(), newDtu.getSpId());
            if ( state !=null && (DEVICE_STATUS_2.equals(state.getDeviceStatus()) ||
                                    DEVICE_STATUS_3.equals(state.getDeviceStatus()) ||
                                    DEVICE_STATUS_6.equals(state.getDeviceStatus()) ) ){
                isAlarmRecovery = true;
            }
        }
        if( isAlarmRecovery ){//v1.0非紫荆报警恢复无需记录探测器编号状态
            recordDetector.setAlertType(ALARM_TYPE_RECOVERY);
        }else{
            recordDetector.setDetectorStatus(t.getDetectorStatus());
        }
        return recordDetector;
    }

    @Override
    protected void saveReceiverValve(DataReportRequest request, Dtu dtu, Long controllerId, ReportNotifyDTO notifyDTO, ReportNotifyOfflineDTO offlineDTO) {
        if (!Constants.ZJ_EQUIPMENT_FROM.equals(dtu.getEquipmentFrom())) return;
        log.info("数据上报的电磁阀信息记录");
        ReceiverValve newReceiverValve = new ReceiverValve();
        LambdaQueryWrapper<ReceiverValve> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ReceiverValve::getDeviceId,dtu.getIMEI());
        ReceiverValve receiverValve = receiverValveService.getOne(queryWrapper);
        //没有接收器和电磁阀并且上报状态是离线，则不做任何操作
        if (request.getValveConnection() == null || VALVE_CONNECTION_0.equals(request.getValveConnection()) &&
                (receiverValve == null || receiverValve.getIsDeleted().equals(1))) {
            log.info("没有接收器和电磁阀并且上报状态是离线，则不做任何操作");
            return;
        } else {
            newReceiverValve.setDeviceId(dtu.getIMEI());
            if (VALVE_CONNECTION_0.equals(request.getValveConnection())) {
                newReceiverValve.setReceiverStatus(RECEIVER_STATUS_OFFLINE);
            } else {
                newReceiverValve.setReceiverStatus(RECEIVER_STATUS_NORMAL);
                if (request.getValveConnection() > 1) {
                    newReceiverValve.setValveId(String.valueOf(request.getValveConnection()));
                }
            }
            //故障
            String valveStatusDesc = request.getValveStatusDesc() == null ? "":request.getValveStatusDesc();
            //电池欠压
            if (valveStatusDesc.contains(VALVE_BROKEN_STATUS_74.toString())) {
                newReceiverValve.setBatteryStatus(BATTERY_STATUS_BROKEN);
            }
            //接收器和电磁阀离线
            if (valveStatusDesc.contains(VALVE_BROKEN_STATUS_71.toString())) {
                newReceiverValve.setReceiverStatus(RECEIVER_STATUS_OFFLINE);
            }
            if (VALVE_WORK_STATUS_1.equals(request.getValveWorkStatus())) {
                newReceiverValve.setBrokenStatus(VALVE_WORK_STATUS_BROKEN);
                if (!StringUtils.isEmpty(valveStatusDesc)) {
                    String brokenStatusInfo = "";
                    if (valveStatusDesc.contains(VALVE_BROKEN_STATUS_70.toString())) {
                        brokenStatusInfo = VALVE_BROKEN_STATUS_70_INFO+";";
                    }
                    if (valveStatusDesc.contains(VALVE_BROKEN_STATUS_71.toString())) {
                        brokenStatusInfo = brokenStatusInfo + VALVE_BROKEN_STATUS_71_INFO+";";
                    }
                    if (valveStatusDesc.contains(VALVE_BROKEN_STATUS_72.toString())) {
                        brokenStatusInfo = brokenStatusInfo + VALVE_BROKEN_STATUS_72_INFO+";";
                    }
                    if (valveStatusDesc.contains(VALVE_BROKEN_STATUS_73.toString())) {
                        brokenStatusInfo = brokenStatusInfo + VALVE_BROKEN_STATUS_73_INFO+";";
                    }
                    newReceiverValve.setBrokenStatusInfo(brokenStatusInfo);
                }
            } else {
                newReceiverValve.setBrokenStatus(VALVE_WORK_STATUS_NORMAL);
                newReceiverValve.setBrokenStatusInfo("");
            }
            if (VALVE_STATUS_0.equals(request.getValveStatus())) {
                newReceiverValve.setValveStatus(VALVE_STATUS_OPEN);
            } else if(VALVE_STATUS_1.equals(request.getValveStatus())){
                newReceiverValve.setValveStatus(VALVE_STATUS_CLOSE);
            }
            newReceiverValve.setSpId(dtu.getSpId());
            if (receiverValve == null) {
                log.info("新增接收器和电磁阀状态更新表："+newReceiverValve.toString());
                receiverValveService.save(newReceiverValve);
            } else {
                if (!valveStatusDesc.contains(VALVE_BROKEN_STATUS_74.toString())) {
                    newReceiverValve.setBatteryStatus(BATTERY_STATUS_NORMAL);
                }
                newReceiverValve.setIsDeleted(0);
                newReceiverValve.setId(receiverValve.getId());
                if (receiverValve.getIsDeleted().equals(1)) {
                    newReceiverValve.setReceiverCode("");
                    newReceiverValve.setReceiverType("");
                    newReceiverValve.setReceiverPowerMode("");
                }
                log.info("更新接收器和电磁阀状态更新表："+newReceiverValve.toString());
                receiverValveService.updateById(newReceiverValve);
            }
            if (notifyDTO !=null) {
                notifyDTO.setReceiverValve(receiverValve);
                notifyDTO.setPrepareReceiverValve(newReceiverValve);
            }
            if (offlineDTO != null) {
                offlineDTO.setReceiverValve(newReceiverValve);
            }
        }
        RecordReceiverValve recordReceiverValve = new RecordReceiverValve();
        recordReceiverValve.setRecordId(controllerId);
        recordReceiverValve.setDeviceId(dtu.getIMEI());
        if (VALVE_CONNECTION_0.equals(request.getValveConnection())) {
            recordReceiverValve.setReceiverStatus(RECEIVER_STATUS_OFFLINE);
        } else {
            recordReceiverValve.setReceiverStatus(RECEIVER_STATUS_NORMAL);
            if (request.getValveConnection() > 1) {
                recordReceiverValve.setValveId(String.valueOf(request.getValveConnection()));
            }
        }
        recordReceiverValve.setValveWorkStatus(request.getValveWorkStatus());
        recordReceiverValve.setValveStatus(request.getValveStatus());
        recordReceiverValve.setBrokenStatus(request.getValveStatusDesc());
        recordReceiverValve.setRecordAt(new Date());
        recordReceiverValve.setSpId(dtu.getSpId());
        log.info("新增接收器和电磁阀上报数据："+recordReceiverValve.toString());
        recordReceiverValveService.save(recordReceiverValve);
    }

    @Override
    protected DeviceState updateDeviceStateByDetector(DataReportDataRequest t, Dtu newDtu, Integer controllerStatus) {
        log.info("updateDeviceStateByDetector start");
        DeviceState deviceState = new DeviceState();
        deviceState.setDeviceId(newDtu.getId());
        deviceState.setConcentration(t.getConcentration());
        deviceState.setSpId(t.getSpId());
        //当修改探测器时, controllerStatus = null
        //探头当前状态
        DeviceState state = getStateByDeviceId(newDtu.getId(), newDtu.getSpId());
        if (state !=null){
            //如果此前未上报过,预设状态为正常
            Integer statusOld = state.getDeviceStatus();
            Boolean isBroken = state.getIsBroken();
            //紫荆WiFi报警器的报警恢复
            if (ALARM_STATUS_0.equals(t.getAlarmStatus()) && (statusOld.equals(EquipmentStatus.alert) ||
                    statusOld.equals(EquipmentStatus.lowAlert) || statusOld.equals(EquipmentStatus.highAlert))){
                deviceState.setDeviceStatus(DEVICE_STATUS_1);
                deviceState.setDeviceStatusInfo(ALARM_TYPE_RECOVERY_INFO);
            } else if (ALARM_STATUS_1.equals(t.getAlarmStatus())){
                //紫荆WiFi报警器的报警
                deviceState.setDeviceStatus(EquipmentStatus.alert);
                deviceState.setDeviceStatusInfo(ALARM_TYPE_ALERT_INFO);
                log.info("设备:{} 紫荆WiFi报警器的报警", deviceState.toString());
                return deviceState;
            }
            if (DETECTOR_STATUS_0.equals(t.getDetectorStatus())) {
                deviceState.setDeviceStatus(DEVICE_STATUS_1);
                deviceState.setDeviceStatusInfo(DEVICE_STATUS_1_INFO);
                log.info("数据上报时设备探头状态的更新:{}", deviceState.toString());
            }

            // 当设备为报警时, 不应去更新设备状态,须由监测上报更新（紫荆WiFi报警器除外）
            // iot接入1.0的协议之后，设备报警恢复走数据上报逻辑，因此1.0报警恢复需要变更状态
            boolean preDeviceStatIsAlarm =  DEVICE_STATUS_2.equals(state.getDeviceStatus()) || DEVICE_STATUS_3.equals(state.getDeviceStatus()) || DEVICE_STATUS_6.equals(state.getDeviceStatus());
            if( "v1.0".equals(newDtu.getProtocolVersion()) && !Constants.ZJ_EQUIPMENT_FROM.equals(newDtu.getEquipmentFrom()) &&
                    preDeviceStatIsAlarm && DETECTOR_STATUS_0.equals(t.getDetectorStatus()) ){
                //设备此前状态是报警，当前状态是正常，报警恢复
                deviceState.setDeviceStatus(DEVICE_STATUS_1);
                deviceState.setDeviceStatusInfo(ALARM_TYPE_RECOVERY_INFO);
                Integer detectorStatus = t.getDetectorStatus();
                if (isBroken) {
                    controllerStatus = DETECTOR_STATUS_0.equals(controllerStatus)?null:controllerStatus;
                    detectorStatus = DETECTOR_STATUS_0.equals(detectorStatus)?null:detectorStatus;
                    //故障->报警->报警恢复时触发的逻辑
                    deviceState.setDeviceStatus(DEVICE_STATUS_4);
                    deviceState.setDeviceStatusInfo(state.getBrokenStatusInfo());
                }
                log.info("v1.0设备:{} 此前状态为报警, 进行状态更新", newDtu.getId());
                setStatusInfo(controllerStatus, detectorStatus, deviceState);
                if (!isBroken) {
                    deviceState.setIsBroken(null);
                    deviceState.setBrokenStatusInfo("");
                }
                log.info("deviceState:{}",JSON.toJSONString(deviceState));
            }else if (!(DEVICE_STATUS_2.equals(state.getDeviceStatus()) || DEVICE_STATUS_3.equals(state.getDeviceStatus()) ||
                    DEVICE_STATUS_6.equals(state.getDeviceStatus())) || Constants.ZJ_EQUIPMENT_FROM.equals(newDtu.getEquipmentFrom())) {
                log.info("设备:{} 此前状态不为报警, 进行状态更新", newDtu.getId());
                setStatusInfo(controllerStatus, t.getDetectorStatus(), deviceState);
            }else {
                log.info("设备:{} 此前状态为报警, 不进行状态更新", newDtu.getId());
            }
        } else {
            setStatusInfo(controllerStatus, t.getDetectorStatus(), deviceState);
        }
        log.info("updateDeviceStateByDetector end");
        return deviceState;

    }

    @Override
    protected RecordController prepareRecordController(DataReportRequest dataReportRequest, Dtu dtu) {
        RecordController recordController = new RecordController();
        recordController.setDeviceId(dtu.getId());
        recordController.setConsumerId(dtu.getConsumerId());
        recordController.setRecordType(dataReportRequest.getRecordType());
        recordController.setControllerStatus(dataReportRequest.getControllerStatus());
        recordController.setRecordAt(dataReportRequest.getReportDate());
        recordController.setSingal(dataReportRequest.getSignal());
        recordController.setPowerModel(dataReportRequest.getPowerMode());
        recordController.setMainBatteryValue(dataReportRequest.getElectricQuantity());
        recordController.setDetectorCount(dataReportRequest.getDetectorNum());
        recordController.setSpId(dtu.getSpId());
        if (null != dataReportRequest.getClockAccuracy()) {
            recordController.setClockAccuracy(dataReportRequest.getClockAccuracy());
        }
        return recordController;
    }

}
